home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / attrib.c < prev    next >
C/C++ Source or Header  |  1993-01-22  |  18KB  |  730 lines

  1. /*    SCCS Id: @(#)attrib.c    3.1    92/10/26    */
  2. /*    Copyright 1988, 1989, 1990, 1992, M. Stephenson          */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /*  attribute modification routines. */
  6.  
  7. #include "hack.h"
  8. #include "artifact.h"
  9.  
  10. /* #define    DEBUG    /* uncomment for debugging info */
  11.  
  12. #ifdef OVLB
  13.  
  14.     /* part of the output on gain or loss of attribute */
  15. static
  16. const char    *plusattr[] = {
  17.     "strong", "smart", "wise", "agile", "tough", "charismatic"
  18. },
  19.         *minusattr[] = {
  20.     "weak", "stupid", "foolish", "clumsy", "vulnerable", "ugly"
  21. };
  22.  
  23.     /* maximum and minimum values for the attributes */
  24. struct attribs    attrmax = {
  25.     118, 18, 18, 18, 18, 18
  26. },
  27.         attrmin = {
  28.     3, 3, 3, 3, 3, 3
  29. };
  30.  
  31. static
  32. const struct innate {
  33.     schar    ulevel;
  34.     long    *ability;
  35.     const char *gainstr, *losestr;
  36. }    a_abil[] = { {     1, &(Stealth), "", "" },
  37.              {   1, &(Fast), "", "" },
  38.              {  10, &(Searching), "perceptive", "" },
  39.              {     0, 0, 0, 0 } },
  40.  
  41.     b_abil[] = { {     1, &(HPoison_resistance), "", "" },
  42.              {   7, &(Fast), "quick", "slow" },
  43.              {  15, &(Stealth), "stealthy", "" },
  44.              {     0, 0, 0, 0 } },
  45.  
  46.     c_abil[] = { {     7, &(Fast), "quick", "slow" },
  47.              {    15, &(Warning), "sensitive", "" },
  48.              {     0, 0, 0, 0 } },
  49.  
  50.     e_abil[] = { {   1, &(Fast), "", "" },
  51.              {     1, &(HSee_invisible), "", "" },
  52.              {     1, &(Searching), "", "" },
  53.              {     1, &(HSleep_resistance), "", "" },
  54.              {     0, 0, 0, 0 } },
  55.  
  56.     h_abil[] = { {     1, &(HPoison_resistance), "", "" },
  57.              {    15, &(Warning), "sensitive", "" },
  58.              {     0, 0, 0, 0 } },
  59.  
  60.     k_abil[] = { {     7, &(Fast), "quick", "slow" },
  61.              {     0, 0, 0, 0 } },
  62.  
  63.     p_abil[] = { {    15, &(Warning), "sensitive", "" },
  64.              {  20, &(HFire_resistance), "cool", "warmer" },
  65.              {     0, 0, 0, 0 } },
  66.  
  67.     r_abil[] = { {     1, &(Stealth), "", ""  },
  68.              {  10, &(Searching), "perceptive", "" },
  69.              {     0, 0, 0, 0 } },
  70.  
  71.     s_abil[] = { {     1, &(Fast), "", "" },
  72.              {  15, &(Stealth), "stealthy", "" },
  73.              {     0, 0, 0, 0 } },
  74.  
  75.     t_abil[] = { {    10, &(Searching), "perceptive", "" },
  76.              {    20, &(HPoison_resistance), "hardy", "" },
  77.              {     0, 0, 0, 0 } },
  78.  
  79.     v_abil[] = { {     1, &(HCold_resistance), "", "" },
  80.              {     1, &(Stealth), "", "" },
  81.              {   7, &(Fast), "quick", "slow" },
  82.              {     0, 0, 0, 0 } },
  83.  
  84.     w_abil[] = { {    15, &(Warning), "sensitive", "" },
  85.              {  17, &(HTeleport_control), "controlled","uncontrolled" },
  86.              {     0, 0, 0, 0 } };
  87.  
  88. static
  89. const struct clattr {
  90.     struct    attribs    base, cldist;
  91.      align    align;
  92.     schar    shp, hd, xlev, ndx;
  93. /* According to AD&D, HD for some classes (ex. Wizard) should be smaller
  94.  * (4-sided for wizards).  But this is not AD&D, and using the AD&D
  95.  * rule here produces an unplayable character.  This I have used a minimum
  96.  * of an 10-sided hit die for everything.  Another AD&D change: wizards get
  97.  * a minimum strength of 6 since without one you can't teleport or cast
  98.  * spells. --KAA
  99.  */
  100.     const struct    innate *abil;
  101. }    a_attr = { {     7, 10, 10,  7,  7,  7 },  /* Archeologist */
  102.            {    20, 20, 20, 10, 20, 10 },
  103.             { A_LAWFUL, 10 },  13, 10, 14,  2, a_abil },
  104.  
  105.     b_attr = { {    16,  7,  7, 15, 16,  6 },  /* Barbarian */
  106.            {    30,  6,  7, 20, 30,  7 },
  107.             { A_NEUTRAL, 10 }, 16, 12, 10,  3, b_abil },
  108.  
  109.     c_attr = { {    10,  7,  7,  7,  8,  6 },  /* Caveman (fighter) */
  110.            {    30,  6,  7, 20, 30,  7 },
  111.              { A_LAWFUL, 0 },  16, 10, 10,  3, c_abil },
  112.  
  113. /*
  114.     e_attr = { {    13, 13, 14,  6, 14,  6 },
  115.  */
  116.     e_attr = { {    13, 13, 13,  9, 13,  7 },  /* Elf (ranger) */
  117.            {    30, 10, 10, 20, 20, 10 },
  118.             { A_CHAOTIC, 10 },  15, 10, 11,  2, e_abil },
  119.  
  120.     h_attr = { {     7,  7, 13,  7, 11, 16 },  /* Healer (druid) */
  121.            {    15, 20, 20, 15, 25, 10 },
  122.             { A_NEUTRAL, 10 },  13, 10, 20,  2, h_abil },
  123.  
  124.     k_attr = { {    13,  7, 14,  8, 10, 17 },  /* Knight (paladin) */
  125.            {    20, 15, 15, 10, 20, 10 },
  126.             { A_LAWFUL, 10 },  16, 10, 10,  3, k_abil },
  127.  
  128.     p_attr = { {     7,  7, 10,  7,  7,  7 },  /* Priest (cleric) */
  129.            {    15, 10, 30, 15, 20, 10 },
  130.             { A_NEUTRAL, 0 },  14, 10, 10,  2, p_abil },
  131.  
  132.     r_attr = { {     7,  7,  7, 10,  7,  6 },  /* Rogue (thief) */
  133.            {    20, 10, 10, 30, 20, 10 },
  134.             { A_CHAOTIC, 10 }, 12, 10, 11,  2, r_abil },
  135.  
  136.     s_attr = { {    10,  8,  7, 10, 17,  6 },  /* Samurai (fighter/thief) */
  137.            {    30, 10, 10, 30, 14, 10 },
  138.             { A_LAWFUL, 10 },  15, 10, 11,  2, s_abil },
  139.  
  140. #ifdef TOURIST
  141.     t_attr = { {     7, 10,  6,  7,  7, 10 },  /* Tourist */
  142.            {    15, 10, 10, 15, 30, 20 },
  143.             { A_NEUTRAL, 0 },  10, 10, 14,  1, t_abil },
  144. #endif
  145.  
  146.     v_attr = { {    10,  7,  7,  7, 10,  7 },  /* Valkyrie (fighter) */
  147.            {    30,  6,  7, 20, 30,  7 },
  148.             { A_NEUTRAL, 0 },  16, 10, 10,  3, v_abil },
  149.  
  150.     w_attr = { {     7, 10,  7,  7,  7,  7 },  /* Wizard (magic-user) */
  151.            {    10, 30, 10, 20, 20, 10 },
  152.             { A_NEUTRAL, 0 },  12, 10, 12,  1, w_abil },
  153.  
  154.     X_attr = { {     3,  3,  3,  3,  3,  3 },
  155.            {    20, 15, 15, 15, 20, 15 },
  156.             { A_NEUTRAL, 0 },  12, 10, 14,  1,  0 };
  157.  
  158. static long next_check = 600L;    /* arbitrary first setting */
  159. static const struct clattr NEARDATA *NDECL(clx);
  160. static void NDECL(init_align);
  161. static void NDECL(exerper);
  162.  
  163. /* adjust an attribute; return TRUE if change is made, FALSE otherwise */
  164. boolean
  165. adjattrib(ndx, incr, msgflg)
  166.     int    ndx, incr;
  167.     int    msgflg;        /* positive => no message, zero => message, and */
  168. {                /* negative => conditional (msg if change made) */
  169.     if (!incr) return FALSE;
  170.  
  171.     if (incr > 0) {
  172.         if ((AMAX(ndx) >= ATTRMAX(ndx)) && (ACURR(ndx) >= AMAX(ndx))) {
  173.         if (msgflg == 0 && flags.verbose)
  174.             pline("You're already as %s as you can get.",
  175.               plusattr[ndx]);
  176.         ABASE(ndx) = AMAX(ndx) = ATTRMAX(ndx); /* just in case */
  177.         return FALSE;
  178.         }
  179.  
  180.         ABASE(ndx) += incr;
  181.         if(ABASE(ndx) > AMAX(ndx)) {
  182.         incr = ABASE(ndx) - AMAX(ndx);
  183.         AMAX(ndx) += incr;
  184.         if(AMAX(ndx) > ATTRMAX(ndx))
  185.             AMAX(ndx) = ATTRMAX(ndx);
  186.         ABASE(ndx) = AMAX(ndx);
  187.         }
  188.     } else {
  189.         if (ABASE(ndx) <= ATTRMIN(ndx)) {
  190.         if (msgflg == 0 && flags.verbose)
  191.             pline("You're already as %s as you can get.",
  192.               minusattr[ndx]);
  193.         ABASE(ndx) = ATTRMIN(ndx); /* just in case */
  194.         return FALSE;
  195.         }
  196.  
  197.         ABASE(ndx) += incr;
  198.         if(ABASE(ndx) < ATTRMIN(ndx)) {
  199.         incr = ABASE(ndx) - ATTRMIN(ndx);
  200.         ABASE(ndx) = ATTRMIN(ndx);
  201.         AMAX(ndx) += incr;
  202.         if(AMAX(ndx) < ATTRMIN(ndx))
  203.             AMAX(ndx) = ATTRMIN(ndx);
  204.         }
  205.     }
  206.     if (msgflg <= 0)
  207.         You("feel %s%s!",
  208.           (incr > 1 || incr < -1) ? "very ": "",
  209.           (incr > 0) ? plusattr[ndx] : minusattr[ndx]);
  210.     flags.botl = 1;
  211.     return TRUE;
  212. }
  213.  
  214. void
  215. gainstr(otmp, incr)
  216.     register struct obj *otmp;
  217.     register int incr;
  218. {
  219.     int num = 1;
  220.  
  221.     if(incr) num = incr;
  222.     else {
  223.         if(ABASE(A_STR) < 18) num = (rn2(4) ? 1 : rnd(6) );
  224.         else if (ABASE(A_STR) < 103) num = rnd(10);
  225.     }
  226.     (void) adjattrib(A_STR, (otmp && otmp->cursed) ? -num : num, TRUE);
  227. }
  228.  
  229. void
  230. losestr(num)    /* may kill you; cause may be poison or monster like 'a' */
  231.     register int num;
  232. {
  233.     int ustr = ABASE(A_STR) - num;
  234.  
  235.     while(ustr < 3) {
  236.         ustr++;
  237.         num--;
  238.         u.uhp -= 6;
  239.         u.uhpmax -= 6;
  240.     }
  241.     (void) adjattrib(A_STR, -num, TRUE);
  242. }
  243.  
  244. void
  245. change_luck(n)
  246.     register schar n;
  247. {
  248.     u.uluck += n;
  249.     if (u.uluck < 0 && u.uluck < LUCKMIN)    u.uluck = LUCKMIN;
  250.     if (u.uluck > 0 && u.uluck > LUCKMAX)    u.uluck = LUCKMAX;
  251. }
  252.  
  253. int
  254. stone_luck(parameter)
  255. boolean parameter; /* So I can't think up of a good name.  So sue me. --KAA */
  256. {
  257.     register struct obj *otmp;
  258.     register long bonchance = 0;
  259.  
  260.     for(otmp = invent; otmp; otmp=otmp->nobj)
  261.         if (otmp->otyp == LUCKSTONE
  262.         || (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) {
  263.         if (otmp->cursed) bonchance -= otmp->quan;
  264.         else if (otmp->blessed) bonchance += otmp->quan;
  265.         else if (parameter) bonchance += otmp->quan;
  266.         }
  267.  
  268.     return sgn((int)bonchance);
  269. }
  270.  
  271. #endif /* OVLB */
  272. #ifdef OVL1
  273.  
  274. void
  275. restore_attrib() {
  276.  
  277.     int    i;
  278.  
  279.     for(i = 0; i < A_MAX; i++) {    /* all temporary losses/gains */
  280.  
  281.        if(ATEMP(i) && ATIME(i)) {
  282.         if(!(--(ATIME(i)))) { /* countdown for change */
  283.             ATEMP(i) += ATEMP(i) > 0 ? -1 : 1;
  284.  
  285.             if(ATEMP(i)) /* reset timer */
  286.             ATIME(i) = 100 / ACURR(A_CON);
  287.         }
  288.         }
  289.     }
  290. }
  291.  
  292. #endif /* OVL1 */
  293. #ifdef OVLB
  294.  
  295. #define AVAL    50        /* tune value for exercise gains */
  296.  
  297. void
  298. exercise(i, inc_or_dec)
  299. int    i;
  300. boolean    inc_or_dec;
  301. {
  302. #ifdef DEBUG
  303.     pline("Exercise:");
  304. #endif
  305.     if (i == A_INT || i == A_CHA) return;    /* can't exercise these */
  306.  
  307. #ifdef POLYSELF
  308.     /* no physical exercise while polymorphed; the body's temporary */
  309.     if (u.umonnum >= 0 && i != A_WIS) return;
  310. #endif
  311.     if(abs(AEXE(i)) < AVAL) {
  312.         /*
  313.          *    Law of diminishing returns (Part I):
  314.          *
  315.          *    Gain is harder at higher attribute values.
  316.          *    79% at "3" --> 0% at "18"
  317.          *    Loss is even at all levels (50%).
  318.          *
  319.          *    Note: *YES* ACURR is the right one to use.
  320.          */
  321.         AEXE(i) += (inc_or_dec) ? (rn2(19) > ACURR(i)) : -rn2(2);
  322. #ifdef DEBUG
  323.         pline("%s, %s AEXE = %d",
  324.             (i == A_STR) ? "Str" : (i == A_WIS) ? "Wis" :
  325.             (i == A_DEX) ? "Dex" : "Con",
  326.             (inc_or_dec) ? "inc" : "dec", AEXE(i));
  327. #endif
  328.     }
  329. }
  330.  
  331. /* hunger values - from eat.c */
  332. #define SATIATED    0
  333. #define NOT_HUNGRY    1
  334. #define HUNGRY        2
  335. #define WEAK        3
  336. #define FAINTING    4
  337. #define FAINTED        5
  338. #define STARVED        6
  339.  
  340. static void
  341. exerper()
  342. {
  343.     if(!(moves % 10)) {
  344.         /* Hunger Checks */
  345.  
  346.         int hs = (u.uhunger > 1000) ? SATIATED :
  347.              (u.uhunger > 150) ? NOT_HUNGRY :
  348.              (u.uhunger > 50) ? HUNGRY :
  349.              (u.uhunger > 0) ? WEAK : FAINTING;
  350.  
  351. #ifdef DEBUG
  352.         pline("exerper: Hunger checks");
  353. #endif
  354.         switch (hs) {
  355.             case SATIATED:    exercise(A_DEX, FALSE); break;
  356.             case NOT_HUNGRY:    exercise(A_CON, TRUE); break;
  357.             case WEAK:        exercise(A_STR, FALSE); break;
  358.             case FAINTING:
  359.             case FAINTED:    exercise(A_CON, FALSE); break;
  360.         }
  361.  
  362.         /* Encumberance Checks */
  363. #ifdef DEBUG
  364.         pline("exerper: Encumber checks");
  365. #endif
  366.         switch (near_capacity()) {
  367.             case MOD_ENCUMBER:    exercise(A_STR, TRUE); break;
  368.             case HVY_ENCUMBER:    exercise(A_STR, TRUE);
  369.                     exercise(A_DEX, FALSE); break;
  370.             case EXT_ENCUMBER:    exercise(A_DEX, FALSE);
  371.                     exercise(A_CON, FALSE); break;
  372.         }
  373.  
  374.     }
  375.  
  376.     /* status checks */
  377.     if(!(moves % 5)) {
  378. #ifdef DEBUG
  379.         pline("exerper: Status checks");
  380. #endif
  381.         if(Clairvoyant)        exercise(A_WIS, TRUE);
  382.         if(HRegeneration)    exercise(A_STR, TRUE);
  383.  
  384.         if(Sick || Vomiting)            exercise(A_CON, FALSE);
  385.         if(Confusion || Hallucination)        exercise(A_WIS, FALSE);
  386.         if(Wounded_legs || Fumbling || HStun)    exercise(A_DEX, FALSE);
  387.     }
  388. }
  389.  
  390. void
  391. exerchk()
  392. {
  393.     int    i, mod_val;
  394.  
  395.     /*    Check out the periodic accumulations */
  396.     exerper();
  397.  
  398. #ifdef DEBUG
  399.     if(moves >= next_check)
  400.         pline("exerchk: ready to test. multi = %d.", multi);
  401. #endif
  402.     /*    Are we ready for a test?    */
  403.     if(moves >= next_check && !multi) {
  404. #ifdef DEBUG
  405.         pline("exerchk: testing.");
  406. #endif
  407.         /*
  408.          *    Law of diminishing returns (Part II):
  409.          *
  410.          *    The effects of "exercise" and "abuse" wear
  411.          *    off over time.  Even if you *don't* get an
  412.          *    increase/decrease, you lose some of the
  413.          *    accumulated effects.
  414.          */
  415.         for(i = 0; i < A_MAX; AEXE(i++) /= 2) {
  416.  
  417.         if(ABASE(i) >= 18 || !AEXE(i)) continue;
  418.         if(i == A_INT || i == A_CHA) continue;/* can't exercise these */
  419.  
  420. #ifdef DEBUG
  421.         pline("exerchk: testing %s (%d).",
  422.             (i == A_STR) ? "Str" : (i == A_WIS) ? "Wis" :
  423.             (i == A_DEX) ? "Dex" : "Con", AEXE(i));
  424. #endif
  425.         /*
  426.          *    Law of diminishing returns (Part III):
  427.          *
  428.          *    You don't *always* gain by exercising.
  429.          *    [MRS 92/10/28 - Treat Wisdom specially for balance.]
  430.          */
  431.         if(rn2(AVAL) > ((i != A_WIS) ? abs(AEXE(i)*2/3) : abs(AEXE(i))))
  432.             continue;
  433.         mod_val = sgn(AEXE(i));
  434.  
  435. #ifdef DEBUG
  436.         pline("exerchk: changing %d.", i);
  437. #endif
  438.         if(adjattrib(i, mod_val, -1)) {
  439. #ifdef DEBUG
  440.             pline("exerchk: changed %d.", i);
  441. #endif
  442.             /* if you actually changed an attrib - zero accumulation */
  443.             AEXE(i) = 0;
  444.             /* then print an explanation */
  445.             switch(i) {
  446.             case A_STR: You((mod_val >0) ?
  447.                     "must have been exercising." :
  448.                     "must have been abusing your body.");
  449.                 break;
  450.             case A_WIS: You((mod_val >0) ?
  451.                     "must have been very observant." :
  452.                     "must not have been paying attention.");
  453.                 break;
  454.             case A_DEX: You((mod_val >0) ?
  455.                     "must have been working on your reflexes." :
  456.                     "haven't been working on reflexes lately.");
  457.                 break;
  458.             case A_CON: You((mod_val >0) ?
  459.                     "must be leading a healthy life-style." :
  460.                     "must not have been watching your health.");
  461.                 break;
  462.             }
  463.         }
  464.         }
  465.         next_check += rn1(200,800);
  466. #ifdef DEBUG
  467.         pline("exerchk: next check at %ld.", next_check);
  468. #endif
  469.     }
  470. }
  471.  
  472. static const struct    clattr *
  473. clx()  {
  474.  
  475.     register const struct    clattr    *attr;
  476.  
  477.     switch    (pl_character[0]) {
  478.  
  479.         case 'A':    attr = &a_attr;
  480.             break;
  481.         case 'B':    attr = &b_attr;
  482.             break;
  483.         case 'C':    attr = &c_attr;
  484.             break;
  485.         case 'E':    attr = &e_attr;
  486.             break;
  487.         case 'H':    attr = &h_attr;
  488.             break;
  489.         case 'K':    attr = &k_attr;
  490.             break;
  491.         case 'P':    attr = &p_attr;
  492.             break;
  493.         case 'R':    attr = &r_attr;
  494.             break;
  495.         case 'S':    attr = &s_attr;
  496.             break;
  497. #ifdef TOURIST
  498.         case 'T':    attr = &t_attr;
  499.             break;
  500. #endif
  501.         case 'V':    attr = &v_attr;
  502.             break;
  503.         case 'W':    attr = &w_attr;
  504.             break;
  505.         default:    /* unknown type */
  506.             attr = &X_attr;
  507.             break;
  508.     }
  509.     return(attr);
  510. }
  511.  
  512. static void
  513. init_align() {    /* called from newhp if u.ulevel is 0 */
  514.  
  515.     register const struct    clattr    *attr = clx();
  516.  
  517.     u.ualign = attr->align;
  518.     /* there should be priests of every stripe */
  519.     if(pl_character[0] == 'P')
  520.          u.ualign.type = (rn2(2)) ? attr->align.type : (rn2(2)) ? 1 : -1;
  521.     else u.ualign.type = attr->align.type;
  522. }
  523.  
  524. void
  525. init_attr(np)
  526.     register int    np;
  527. {
  528.     register int    i, x, tryct;
  529.     register const struct    clattr    *attr = clx();
  530.  
  531.     for(i = 0; i < A_MAX; i++) {
  532.  
  533.         ABASE(i) = AMAX(i) = attr->base.a[i];
  534.         ATEMP(i) = ATIME(i) = 0;
  535.         np -= attr->base.a[i];
  536.     }
  537.  
  538.     tryct = 0;
  539.     while(np > 0 && tryct < 100) {
  540.  
  541.         x = rn2(100);
  542.         for (i = 0; (i < A_MAX) && ((x -= attr->cldist.a[i]) > 0); i++) ;
  543.         if(i >= A_MAX) continue; /* impossible */
  544.  
  545.         if(ABASE(i) >= ATTRMAX(i)) {
  546.  
  547.         tryct++;
  548.         continue;
  549.         }
  550.         tryct = 0;
  551.         ABASE(i)++;
  552.         AMAX(i)++;
  553.         np--;
  554.     }
  555.  
  556.     tryct = 0;
  557.     while(np < 0 && tryct < 100) {        /* for redistribution */
  558.  
  559.         x = rn2(100);
  560.         for (i = 0; (i < A_MAX) && ((x -= attr->cldist.a[i]) > 0); i++) ;
  561.         if(i >= A_MAX) continue; /* impossible */
  562.  
  563.         if(ABASE(i) <= ATTRMIN(i)) {
  564.  
  565.         tryct++;
  566.         continue;
  567.         }
  568.         tryct = 0;
  569.         ABASE(i)--;
  570.         AMAX(i)--;
  571.         np++;
  572.     }
  573. }
  574.  
  575. void
  576. redist_attr() {
  577.  
  578.     register int i, tmp;
  579.  
  580.     for(i = 0; i < A_MAX; i++) {
  581.         if (i==A_INT || i==A_WIS) continue;
  582.         /* Polymorphing doesn't change your mind */
  583.         tmp = AMAX(i);
  584.         AMAX(i) += (rn2(5)-2);
  585.         if (AMAX(i) > ATTRMAX(i)) AMAX(i) = ATTRMAX(i);
  586.         if (AMAX(i) < ATTRMIN(i)) AMAX(i) = ATTRMIN(i);
  587.         ABASE(i) = ABASE(i) * AMAX(i) / tmp;
  588.         /* ABASE(i) > ATTRMAX(i) is impossible */
  589.         if (ABASE(i) < ATTRMIN(i)) ABASE(i) = ATTRMIN(i);
  590.     }
  591. }
  592.  
  593. void
  594. adjabil(oldlevel,newlevel)
  595. int oldlevel, newlevel;
  596. {
  597.     register const struct clattr    *attr = clx();
  598. #ifdef GCC_WARN
  599.     /* this is the "right" definition */
  600.     register const struct innate    *abil = attr->abil;
  601. #else
  602.     /* this one satisfies more compilers */
  603.     register struct innate    *abil = (struct innate *)attr->abil;
  604. #endif
  605.  
  606.     if(abil) {
  607.         for(; abil->ability; abil++) {
  608.         if(oldlevel < abil->ulevel && newlevel >= abil->ulevel) {
  609.             /* Abilities gained at level 1 can never be lost
  610.              * via level loss, only via means that remove _any_
  611.              * sort of ability.  A "gain" of such an ability from
  612.              * an outside source is devoid of meaning, so we set
  613.              * FROMOUTSIDE to avoid such gains.
  614.              */
  615.             if (abil->ulevel == 1)
  616.                 *(abil->ability) |= (FROMEXPER|FROMOUTSIDE);
  617.             else
  618.                 *(abil->ability) |= FROMEXPER;
  619.             if(!(*(abil->ability) & FROMOUTSIDE)) {
  620.                 if(*(abil->gainstr))
  621.                 You("feel %s!", abil->gainstr);
  622.             }
  623.         } else if (oldlevel >= abil->ulevel && newlevel < abil->ulevel) {
  624.             *(abil->ability) &= ~FROMEXPER;
  625.             if((*(abil->ability) & INTRINSIC)) {
  626.                 if(*(abil->losestr))
  627.                 You("feel %s!", abil->losestr);
  628.                 else if(*(abil->gainstr))
  629.                 You("feel less %s!", abil->gainstr);
  630.             }
  631.         }
  632.         }
  633.     }
  634. }
  635.  
  636. int
  637. newhp() {
  638.     register const struct clattr    *attr = clx();
  639.     int    hp, conplus;
  640.  
  641.     if(u.ulevel == 0) {
  642.  
  643.         hp = attr->shp;
  644.         init_align();    /* initialize alignment stuff */
  645.         return hp;
  646.     } else {
  647.  
  648.         if(u.ulevel < attr->xlev)
  649.         hp = rnd(attr->hd);
  650.         else
  651.         hp = attr->ndx;
  652.     }
  653.  
  654.     switch(ACURR(A_CON)) {
  655.         case    3:    conplus = -2; break;
  656.         case    4:
  657.         case    5:
  658.         case    6:    conplus = -1; break;
  659.         case    15:
  660.         case    16:    conplus = 1; break;
  661.         case    17:    conplus = 2; break;
  662.         case    18:    conplus = 3; break;
  663.         default:    conplus = 0;
  664.     }
  665.     hp += conplus;
  666.     return((hp <= 0) ? 1 : hp);
  667. }
  668.  
  669. #endif /* OVLB */
  670. #ifdef OVL0
  671.  
  672. schar
  673. acurr(x)
  674. int x;
  675.     register int tmp = (u.abon.a[x] + u.atemp.a[x] + u.acurr.a[x]);
  676.  
  677.     if (x == A_STR) {
  678.         if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER) return(125);
  679.         else return((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp);
  680.     } 
  681. #ifdef POLYSELF
  682.     else if(x == A_CHA) {
  683.         if (tmp < 18 && (u.usym == S_NYMPH ||
  684.             u.umonnum==PM_SUCCUBUS || u.umonnum == PM_INCUBUS))
  685.             return 18;
  686.     }
  687. #endif
  688.     return((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp);
  689. }
  690.  
  691. schar
  692. acurrstr()
  693. /* condense clumsy ACURR(A_STR) value into value that fits into game formulas
  694.  */
  695. {
  696.     register int str = ACURR(A_STR);
  697.  
  698.     if (str <= 18) return str;
  699.     if (str <= 121) return (19 + str / 50); /* map to 19-21 */
  700.     else return str - 100;
  701. }
  702.  
  703. #endif /* OVL0 */
  704. #ifdef OVL2
  705.  
  706. /* avoid possible problems with alignment overflow, and provide a centralized
  707.  * location for any future alignment limits
  708.  */
  709. void
  710. adjalign(n)
  711. register int n;
  712. {
  713.     register int newalign = u.ualign.record + n;
  714.  
  715.     if(n < 0) {
  716.         if(newalign < u.ualign.record)
  717.             u.ualign.record = newalign;
  718.     } else
  719.         if(newalign > u.ualign.record) {
  720.             u.ualign.record = newalign;
  721.             if(u.ualign.record > ALIGNLIM)
  722.                 u.ualign.record = ALIGNLIM;
  723.         }
  724. }
  725.  
  726. #endif /* OVL2 */
  727.  
  728. /*attrib.c*/
  729.